﻿using ExcelUnity.Core;
using ExcelUnity.Importer.Importers;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace ExcelUnity.Importer.Wrappers.SheetWraperBuilders
{
    /// <summary>
    /// 列绑定器
    /// </summary>
    public class ColumnWrapperBinder
    {
        /// <summary>
        /// 将列与DataType绑定
        /// </summary>
        /// <param name="columnWrappers"></param>
        /// <param name="dataType"></param>
        /// <param name="columnMatchType"></param>
        /// <returns></returns>
        public static string? BindColumWrapperToDataType(List<ColumnWrapper> columnWrappers, Type dataType, ColumnMatchType columnMatchType)
        {
            //datatable或dinamic
            if (dataType == typeof(DataTable) || dataType.FullName == "System.Object")
            {
                columnWrappers.ForEach(x => x.PropertyName = x.ColumnName);
                return null;
            }

            //用沪自定义类型
            var notMatchColumnSign = new List<string>();
            var columnProperties = BuildProperties(dataType, columnMatchType);
            foreach (var property in columnProperties)
            {
                var column = columnWrappers.FirstOrDefault(x => columnMatchType == ColumnMatchType.ColumnIndex ? x.ColumnIndex == property.MatchColumnIndex : x.ColumnName == property.MatchColumnName);
                if (column != null)
                {
                    column.ColumnProperty = property;
                    column.PropertyName = property.PropertyInfo.Name;
                }
                else if (property.IsRequired)
                    notMatchColumnSign.Add(columnMatchType == ColumnMatchType.ColumnIndex ? property.MatchColumnIndex.ToString() : property.MatchColumnName ?? string.Empty);
            }

            return notMatchColumnSign.Any() ? $"未找到列: {string.Join(",", notMatchColumnSign)}" : null;
        }


        /// <summary>
        /// 根据表头解析Excel的列与导出结果的列对应关系
        /// </summary>
        /// <param name="modelType"></param>
        /// <param name="columnMatchType"></param>
        /// <param name="headerRow"></param>
        /// <returns></returns>
        private static List<ColumnProperty> BuildProperties(Type modelType, ColumnMatchType columnMatchType)
        {
            var ret = columnMatchType switch
            {
                ColumnMatchType.ColumnName => modelType.GetProperties()
                                                 .Select(x => new { Property = x, Attr = x.GetCustomAttribute(typeof(ColumnNameAttribute)) })
                                                 .Where(x => x.Attr != null)
                                                 .Select(x => new ColumnProperty(x.Property, (ColumnNameAttribute)x.Attr))
                                                 .ToList(),
                ColumnMatchType.ColumnIndex => modelType.GetProperties()
                                              .Select(x => new { Property = x, Attr = x.GetCustomAttribute(typeof(ColumnIndexAttribute)) })
                                              .Where(x => x.Attr != null)
                                              .Select(x => new ColumnProperty(x.Property, (ColumnIndexAttribute)x.Attr))
                                              .ToList(),
                _ => new List<ColumnProperty>(),
            };

            // 没有字段设置唯一认证，则给所有字段加上唯一认证
            if (!ret.Any(m => m.IsUnique)) ret.ForEach(m => m.IsUnique = true);

            return ret;
        }
    }
}
